from sqlalchemy.orm import Session
from sqlalchemy import update
from . import models, schemas
from datetime import datetime
from domain.response import success, error
from constant.admin_constants import *
from utils import snowflaker


# @张寒萌
# 模板可参考crud.py
async def get_version(bid: str, db: Session):
    return db.query(models.Version).filter(models.Version.bid == bid).first()


async def open_version(bid: str, msg: str, db: Session):
    # get version
    version = db.query(models.Version).filter(models.Version.bid == bid).first()
    # has been deleted
    if version.is_delete == 1:
        return
    # set open
    version.is_release = 1
    # add a message
    # todo: bid & user_bid
    workerValue = snowflaker.IdWorker(1, 2, 0).get_id()
    bid = "V" + str(workerValue)
    version_msg = models.VersionMessage(bid=bid, version_bid=bid, operation=OPEN_VERSION, user_bid='', content=msg,
                                        create_time=datetime.now())
    db.add(version_msg)
    db.commit()
    return version


async def close_version(bid: str, msg: str, db: Session):
    # get version
    version = db.query(models.Version).filter(models.Version.bid == bid).first()
    # has been deleted
    if version.is_delete == 1:
        return
    # set close
    version.is_release = 0
    # add a message
    # todo: bid & user_bid
    version_msg = models.VersionMessage(bid='', version_bid=bid, operation=4, user_bid='', content=msg,
                                        create_time=datetime.now())
    db.add(version_msg)
    db.commit()
    return version


async def delete_version(bid: str, msg: str, db: Session):
    # get version
    version = db.query(models.Version).filter(models.Version.bid == bid).first()
    # has been deleted
    if version.is_delete == 1:
        return
    # set deleted and add delete time
    version.is_release = 0
    version.delete_time = datetime.now()
    # add a message
    # todo: bid & user_bid
    version_msg = models.VersionMessage(bid='', version_bid=bid, operation=3, user_bid='', content=msg,
                                        create_time=datetime.now())
    db.add(version_msg)
    db.commit()
    return version


def version_str2int(vstr: str):
    vint = 0
    cnt = 4

    for v in vstr.split('.'):
        vint = vint * 10 ** 2 + int(v)
        cnt -= 1

    for i in range(cnt):
        vint *= 10 ** 2

    return vint


async def add_version(bid: str, version: schemas.VersionCreate, msg: str, db: Session):
    version_new = models.Version(bid=version.bid, version=version_str2int(version.version), md5=version.md5,
                                 download_url=version.download_url, max_os_api=version.max_os_api,
                                 min_os_api=version.min_os_api, max_version=version_str2int(version.max_version),
                                 min_version=version_str2int(version.min_version),
                                 cpu_arch=version.cpu_arch, channel=version.channel, pop_count=0, install_count=0,
                                 create_time=datetime.now(), delete_time=None, is_delete=0, is_release=0)
    # add a version
    db.add(version_new)
    # add a message
    # todo: bid & user_bid
    version_msg = models.VersionMessage(bid='', version_bid=version.bid, operation=1, user_bid='', content=msg,
                                        create_time=datetime.now())
    db.add(version_msg)
    db.commit()
    return version_new


async def update_version(version: schemas.VersionCreate, msg: str, db: Session):
    # get version
    version_update = db.query(models.Version).filter(models.Version.bid == version.bid).first()

    # has been deleted
    if version_update.is_delete == 1:
        return error(code=41001, msg='This version has been deleted!')

    # is online
    if version_update.is_release == 1:
        return error(code=41011, msg='This version has been open!')

    # update a version
    version_update.version = version_str2int(version.version)
    version_update.md5 = version.md5
    version_update.download_url = version.download_url
    version_update.max_os_api = version.max_os_api
    version_update.min_os_api = version.min_os_api
    version_update.max_version = version_str2int(version.max_version)
    version_update.min_version = version_str2int(version.min_version)
    version_update.cpu_arch = version.cpu_arch
    version_update.channel = version.channel

    # add a message
    # todo: bid & user_bid
    version_msg = models.VersionMessage(bid='', version_bid=version.bid, operation=2, user_bid='', content=msg,
                                        create_time=datetime.now())
    db.add(version_msg)
    db.commit()
    return version_update
